#!C:\soft\perl\bin\perl.exe
require PostConf;
require GenMonitor;

$charset = 'windows-1251';
$showtimes = 1 unless defined $showtimes;
$scrname = 'monitor.pl' unless defined $scrname;

# get path info
$pathinfo = $ENV{'PATH_INFO'};
# get query
if ($ENV{'REQUEST_METHOD'} eq 'GET') { $query = $ENV{'QUERY_STRING'}; }
elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { 
  read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); }
# parse command-line parameters
while (my $i = shift (@ARGV)) {
  $query = shift (@ARGV) if ($i eq '-q');
  $pathinfo = shift (@ARGV) if ($i eq '-p');
  $no_http = 1 if ($i eq '-n');
}

# split into pairs (name,value)
@pairs = split(/&/, $query);
foreach $pair (@pairs) {
   my ($name, $value) = split(/=/, $pair);
   $value =~ tr/+/ /;
   $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   $value =~ s/<!--(.|\n)*-->//g;
   $value =~ s/<([^>]|\n)*>//g;
   $FORM{$name} = $FORM{$name} ? $FORM{$name} . '+' . $value : $value;
}

sub load_contests {
    my $cut_time = time - 86400;
    opendir DIR, $workdir || die "cannot open directory $workdir";
    @files = grep { /^[^\.]/ && /^[A-Za-z0-9\.\-_]{1,16}$/ && 
			-f "$workdir/$_" && -r "$workdir/$_"} readdir(DIR);
    closedir DIR;
    @list = ();
    while ($fn = shift @files) {
	$data = '';  $info = '';
	open FILE, "$workdir/$fn" || die "cannot open $workdir/$fn";
	($size,$time) = (stat FILE)[7,9];
	binmode FILE;
	$len = $size>32767 ? 24576 : 16384;
	sysread FILE, $data, $len;
	close FILE;
	$data =~ s/\r\n/\n/g;
	($info, $startat, $contlen, $now, $state) = 
	    ($data =~ /^\@contest\s+([^\r\n]+)\n\@startat\s+(\d\d.\d\d.\d{4} \d\d:\d\d:\d\d|undefined)\n\@contlen\s+(\d+)\n\@now\s+(\d+)\n\@state\s+(\w+)$/m);
	$info = $1, $info =~ s/\\\"/&quot;/g if ($info =~ /^\s*\"(.*)\"$/);
	$key = "$3$2$1$4$5$6" if ($startat =~ /(\d\d).(\d\d).(\d{4}) (\d\d):(\d\d):(\d\d)/);
	$key = 1e15 if ($startat eq 'undefined' && $time > $cut_time);
	push @list, [$fn, $key, $time, $size, $info, $startat, $contlen, $now, $state]
	    if $info;
  }
  return @list = sort {$$b[1] <=> $$a[1] || $$b[2] <=> $$a[2]} @list;
}

($fn) = ($pathinfo =~ /^\/([A-Za-z0-9][A-Za-z0-9\-_\.]{0,16})$/);

if ($fn eq 'current') {
  @list = load_contests();
  $fn = $list[0][0];
}

$self = $fn ? $fn : $scrname;
$refresh = $FORM{'refresh'};
$refresh = '' if ($refresh < 5 || $refresh > 14400);
$refline = $refresh ? "Refresh: $refresh;URL=$self?refresh=$refresh\n" : '';

if ($pathinfo eq '') {
  print <<END;
Content-type: text/html; charset=$charset
Pragma: no-cache
Expires: now
$refline
<HTML><HEAD><TITLE>View Contest Results</TITLE></HEAD>
<BODY><H1>View Contest Results</H1>
<TABLE BORDER=1 CELLPADDING=4>
<TR><TH>Contest</TH><TH>Start</TH><TH>Duration</TH><TH>State</TH><TH>Last Updated</TH></TR>
END
@list = load_contests();
while ($ref = shift @list) {
  ($fn, $key, $time, $size, $info, $startat, $contlen, $now, $state) = @$ref;
  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime ($time);
  $date = sprintf ("%02d.%02d.%04d %02d:%02d:%02d", 
	$mday, $mon + 1, $year + 1900, $hour, $min, $sec);
  if (($state eq 'RUNNING' || $state eq 'FROZEN') && $now < $contlen*60) {
    $state = $state . ' ' . int($now/60) . '/' . $contlen; }
  $contlen = sprintf ('%d:%02d', int($contlen/60), $contlen%60);
  $info =~ s/&quot;/\"/g;
  $info =~ s/&/&amp;/g;
  $info =~ s/</&lt;/g;
  $info =~ s/>/&gt;/g;
  $info =~ s/\"/&quot;/g;
  print <<ROW;
<TR><TD><A HREF=$scrname/$fn>$info</A></TD><TD>$startat</TD><TD>$contlen</TD>
    <TD>$state</TD><TD>$date</TD></TR>
ROW
}
print "</TABLE></BODY></HTML>\n";
exit; }

die "invalid path" unless ($fn ne '');
open FILE, "<$workdir/$fn" or die "cannot open $workdir/$fn";
($size,$time) = (stat FILE)[7,9];
die "file $fn empty" if ($size <= 0);
die "file $fn too long" if ($size > $maxlen);
binmode FILE;
sysread FILE, $data, $size;
close FILE;

sub error {
  my $err = shift;
  $_ = $err;  s/&/&amp;/g;  s/</&lt;/g;  s/>/&gt;/g;  
  print <<ERR;
Content-type: text/plain
Pragma: no-cache
Expires: now

<HTML><BODY>Monitor file "$fn" parse error on line $lno: <I>$_</I></BODY></HTML>
ERR
  die "Parse error: $err";
}


$Monitor = GenMonitor ($data, $showtimes, int($FORM{'when'}), int($FORM{'s'}));

if ($MonError) {
    $lno = $MonLine;
    error ($MonError);
    exit;
}

print <<END;
Content-type: text/html; charset=$charset
Pragma: no-cache
Expires: now
$refline
<HTML><HEAD><TITLE>$contname</TITLE>
<LINK HREF=$css REL=stylesheet TYPE=text/css></HEAD>
<BODY><H2>$contname</H2>
$Monitor
<P><A HREF=../$scrname>List of all contests</A></P>
<A HREF=$self?refresh=$default_refresh>Auto-refresh</A>
</BODY></HTML>
END
